package com.htfyun.factorytest.factorytestui;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.htfyun.factorytest.RootApplication;
import com.htfyun.factorytest.iflytekWakeup.HtfyunWakeupEngine;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;

import com.htfyun.factorytest.R;

import com.htfyun.factorytest.common.Constants;
import com.htfyun.factorytest.config.EinkProperty;
import com.htfyun.factorytest.device.DeviceAttr;
import com.htfyun.factorytest.engineer_test.FragmentES7210_MonoTest;
import com.htfyun.factorytest.engineer_test.OnBtnResultForES7210;
import com.htfyun.factorytest.utils.DebugLog;

/**
 * Created by sst on 2018/7/10.
 */

public class FactoryThirdActivity extends FactoryBaseActivity implements WakeuperListener {

    private Button mBtnPower;
    private Button mBtnHome;
    private Button mBtnHall;
    private Button mBtnBack;
    private Button mBtnVolumeUp;
    private Button mBtnVolumeDown;
    private Button mBtnDrag;
    private Button mBtnRefresh;
    private Button mBtnSlide;
    private Button mBtnPageUp, mBtnPageDown, mBtnSearch, mBtnF2;

    private int FLAG_KEY_TEST = Constants.FLAG_KEY_TEST;

    ////////////////////////////////////////////////
    private int wakeupCount = 0;
    private static final int WAKE_UP_TIME_SECOND = 40;
    private static final int SUCCESS_WAKEUP_COUNT = 3;

    private View layoutWakeup;
    private TextView txtStatus;
    private TextView txtCount;
    private TextView thirdTips;
    private TextView txtTips;
    private TextView txtCountDown;

    private boolean canWakeup = false;
    private int wakeupCountDown = WAKE_UP_TIME_SECOND;


    private static final int MSG_WAKEUP_COUNT_DOWN = 1000;
    private static final int PERIOD_WAKEUP_COUNT_DOWN = 1000;

    private HtfyunWakeupEngine wakeupEngine;

    private FragmentES7210_MonoTest fragmentES7210;
    private OnBtnResultForES7210 onBtnResultForES7210 = new OnBtnResultForES7210() {
        @Override
        public void onBtnResultForES7210(boolean pass) {
            if (pass) {
                txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_pass)));
                finishWithOK();
            } else {
                txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_fail)));
                finishWithFail();
            }
            stopWakeupTest();

        }
    };

    @Override
    int getLayoutId() {
        return R.layout.activity_factory_third;
    }

    @Override
    void onInitView(@Nullable Bundle savedInstanceState) {

        mBtnPower = findViewById(R.id.btnPower);
        mBtnHome = findViewById(R.id.btnHome);
        mBtnHall = findViewById(R.id.btnHall);
        mBtnBack = findViewById(R.id.btnBack);
        mBtnVolumeUp = findViewById(R.id.btnVolumeUp);
        mBtnVolumeDown = findViewById(R.id.btnVolumeDown);
        mBtnDrag = findViewById(R.id.btnDrag);
        mBtnRefresh = findViewById(R.id.btnRefresh);
        mBtnSlide = findViewById(R.id.btnSlide);

        mBtnPageUp = findViewById(R.id.btnPageUp);
        mBtnPageDown = findViewById(R.id.btnPageDown);
        mBtnSearch = findViewById(R.id.btnSearch);
        mBtnF2 = findViewById(R.id.btnF2);

        txtStatus = findViewById(R.id.txtStatus);
        txtCount = findViewById(R.id.txtCount);
        thirdTips = findViewById(R.id.thirdTips);
        txtTips = findViewById(R.id.txtTips);
        txtCountDown = findViewById(R.id.txtCountDown);

        if (!DeviceAttr.getRunningDeviceAttr().hasMicrophone()) {
            thirdTips.setText(R.string.ft_third_tips_no_mic);
        }

        isExistKey();

        txtTips.setText(getString(R.string.test_wakeup_tips, WAKE_UP_TIME_SECOND));
        txtCount.setText(getString(R.string.wakeup_success_count, 0, (SUCCESS_WAKEUP_COUNT)));
        txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.wakeup_status_start_recognition)));

        layoutWakeup = findViewById(R.id.layoutWakeup);
        layoutWakeup.setVisibility(EinkProperty.isES7210Record() ? View.GONE : View.INVISIBLE);
        View container = findViewById(R.id.container);
        if (container != null) {
            container.setVisibility(EinkProperty.isES7210Record() ? View.VISIBLE : View.GONE);
        }

    }

    private void isExistKey() {
        if (!RootApplication.isExistVolumeKey) {
            mBtnVolumeUp.setVisibility(View.GONE);
            mBtnVolumeDown.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_VOLUME_UP;
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_VOLUME_DOWN;
        }

        if (!RootApplication.isExistHomeKey) {
            mBtnHome.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_HOME;
        }

        if (!RootApplication.isExistBackKey) {
            mBtnBack.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_BACK;
        }

        if (!RootApplication.isExistHallKey) {
            mBtnHall.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_HALL;
        }

        if (!RootApplication.isExistDragKey) {
            mBtnDrag.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_DRAG;
        }

        if (!RootApplication.isExistRefreshKey) {
            mBtnRefresh.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_REFRESH;
        }

        if (!RootApplication.isExistSlideKey) {
            mBtnSlide.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_SLIDE;
        }

        if (!RootApplication.isExistPageUpKey) {
            mBtnPageUp.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_PAGE_UP;
        }

        if (!RootApplication.isExistPageDownKey) {
            mBtnPageDown.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_PAGE_DOWN;
        }

        if (!RootApplication.isExistSearchKey) {
            mBtnSearch.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_SEARCH;
        }

        if (!RootApplication.isExistF2Key) {
            mBtnF2.setVisibility(View.GONE);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_F2;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        EinkProperty.setEinkFactoryTestEnabled(true);
    }

    @Override
    protected void onPause() {
        super.onPause();
        EinkProperty.setEinkFactoryTestEnabled(false);
    }

/*    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_POWER) {
            mBtnPower.setSelected(true);
            DebugLog.e("dispatchKeyEvent KEYCODE_POWER");
            pass(mBtnPower);
            flagKeyTest &= ~Constants.FLAG_KEY_POWER;
            return true;
        } else if (keyCode == Constants.KEYCODE_REFRESH) {
            return true;
        }
        return super.dispatchKeyEvent(event);
    }*/

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        DebugLog.d("onKeyDown keyCode = " + keyCode);
        if (keyCode == KeyEvent.KEYCODE_HOME) {
            mBtnHome.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
            mBtnBack.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_POWER) {
            DebugLog.e("Power KeyDown");
            mBtnPower.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_SLEEP) {
            mBtnHall.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            mBtnVolumeUp.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            mBtnVolumeDown.setSelected(true);
            return true;

        } else if (keyCode == Constants.KEYCODE_DRAG) {
            mBtnDrag.setSelected(true);
            return true;

        } else if (keyCode == Constants.KEYCODE_REFRESH) {
            mBtnRefresh.setSelected(true);
            return true;

        } else if (keyCode == Constants.KEYCODE_SLIDE) {
            mBtnSlide.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
            mBtnPageUp.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
            mBtnPageDown.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
            mBtnSearch.setSelected(true);
            return true;

        } else if (keyCode == KeyEvent.KEYCODE_F2) {
            mBtnF2.setSelected(true);
            return true;
        }

        return super.onKeyDown(keyCode, event);

    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {

        boolean ret = true;

        if (keyCode == KeyEvent.KEYCODE_HOME) {
            pass(mBtnHome);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_HOME;

        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
            pass(mBtnBack);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_BACK;

        } else if (keyCode == KeyEvent.KEYCODE_POWER) {
            DebugLog.e("Power KeyUp");
            pass(mBtnPower);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_POWER;

        } else if (keyCode == KeyEvent.KEYCODE_SLEEP) {
            pass(mBtnHall);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_HALL;

        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            pass(mBtnVolumeUp);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_VOLUME_UP;

        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            pass(mBtnVolumeDown);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_VOLUME_DOWN;

        } else if (keyCode == Constants.KEYCODE_DRAG) {
            pass(mBtnDrag);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_DRAG;

        } else if (keyCode == Constants.KEYCODE_REFRESH) {
            pass(mBtnRefresh);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_REFRESH;

        } else if (keyCode == Constants.KEYCODE_SLIDE) {
            pass(mBtnSlide);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_SLIDE;

        } else if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
            pass(mBtnPageUp);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_PAGE_UP;

        } else if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
            pass(mBtnPageDown);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_PAGE_DOWN;

        } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
            pass(mBtnSearch);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_SEARCH;

        } else if (keyCode == KeyEvent.KEYCODE_F2) {
            pass(mBtnF2);
            FLAG_KEY_TEST &= ~Constants.FLAG_KEY_F2;
        } else {

            ret = false;
        }

        if (ret && FLAG_KEY_TEST == 0) {
            DebugLog.i("flagKeyTest = " + FLAG_KEY_TEST);
            if (!DeviceAttr.getRunningDeviceAttr().hasMicrophone()) {
                finishWithOK();
            } else {
                startWakeupTest();
            }
        }

        return ret || super.onKeyUp(keyCode, event);
    }

    private void pass(Button button) {
        button.setSelected(false);
        button.setText(getNewTextForBtn(button, getResources().getString(R.string.test_ok)));
    }

    private String getNewTextForBtn(Button btn, String test_status) {
        String text = btn.getText().toString();
        String arrow = getResources().getString(R.string.arrow);
        String[] rmStatus = text.split(arrow);
        if (rmStatus.length > 1) {
            text = rmStatus[0];
        }
        return (text + arrow + test_status);
    }


    /////////////////////////////////////////////////////////////

    private synchronized void startWakeupTest() {
        if (EinkProperty.isES7210Record()) {
            if (fragmentES7210 == null) {
                fragmentES7210 = new FragmentES7210_MonoTest();
                fragmentES7210.setOnBtnResultForES7210(onBtnResultForES7210);
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.container, fragmentES7210)
                        .commit();
            }
            return;
        }
        if (layoutWakeup.getVisibility() == View.VISIBLE) {
            //已经开始唤醒测试了.
            return;
        }
        layoutWakeup.setVisibility(View.VISIBLE);
        startRecognition();
        updateCountdown();
    }

    private synchronized void stopWakeupTest() {
        layoutWakeup.setVisibility(View.INVISIBLE);
        stopRecognition();
        getHandler().removeMessages(MSG_WAKEUP_COUNT_DOWN);
    }


    @Override
    void onHandleMessage(Handler handler, Message msg) {

        switch (msg.what) {
            case MSG_WAKEUP_COUNT_DOWN:
                updateCountdown();
                break;
        }
    }

    private void startRecognition() {
        destroyIflytekVoiceRecognition();

        wakeupEngine = new HtfyunWakeupEngine(this);
        wakeupEngine.setWakeuperListener(this);
        wakeupEngine.start();

        canWakeup = true;
        txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.wakeup_status_doing)));
    }

    private void stopRecognition() {
        destroyIflytekVoiceRecognition();
    }

    private void handleRecognition() {
        if (wakeupCount < 0) {
            return;
        }

        txtCount.setText(getString(R.string.wakeup_success_count, wakeupCount, (SUCCESS_WAKEUP_COUNT - wakeupCount)));

        if (wakeupCount >= SUCCESS_WAKEUP_COUNT) {
            canWakeup = false;
            txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_pass)));

            stopWakeupTest();

            finishWithOK();

        } else if (!canWakeup) {

            txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_fail)));
        }
    }

    private void updateCountdown() {

        if (wakeupCountDown <= 0) {
            finishWithFail();
        }

        handleRecognition();

        wakeupCountDown--;
        txtCountDown.setText(getString(R.string.wakeup_test_countdown, wakeupCountDown));

        getHandler().sendEmptyMessageDelayed(MSG_WAKEUP_COUNT_DOWN, PERIOD_WAKEUP_COUNT_DOWN);
    }

    private void destroyIflytekVoiceRecognition() {

        if (wakeupEngine != null) {
            wakeupEngine.destroy();
            wakeupEngine = null;
        }

    }

    @Override
    public void onBeginOfSpeech() {

    }

    @Override
    public void onResult(WakeuperResult result) {
        DebugLog.d("onResult");
        wakeupCount++;
//        updateCountdown();
    }

    @Override
    public void onError(SpeechError speechError) {
        DebugLog.e(speechError.getPlainDescription(true));
    }

    @Override
    public void onEvent(int i, int i1, int i2, Bundle bundle) {

    }

    @Override
    public void onVolumeChanged(int i) {

    }
}
